<?php
/**
 * 简单工厂
 *
 * 在不同的条件下需要使用同一类型的不用产品 , 可以使用简单工厂
 * 不用在客户端去判断后实例化 , 将判断封装到工厂里面去
 * */


/**
 * 二次看简单工厂:
 *      定义一个工厂类 , 他可以根据参数不同而返回不同的实例 , 通常 所返回的实例都有一定的共性 , 也就是说有公共的基类或者接口
 *
 *
 *      使用简单工厂有什么好处呢 ?
 *          1. 客户端不 只需要 得到实例去调用对应方法完成业务即可 , 而不需要自己将 对象的获取操作硬编码
 *          2. 对象的创建 , 也是一种职责 , 可能某些对象的创建过程比较复杂 , 如果每次都需要在客户端去判断 , 那么会出现大量的对象实例化代码
 *          3. 使用工厂来创建对象可以对 客户端进行风险隔离: 某一天该实例不在需要 , 或者构造的时候需要其他的操作 , 不必再去修改客户端的代码, 而是对工厂进行修改
 *              测试的时候只需要测试对应的工厂能否生成正确的实例, 以及该实例能否正常的工作即可 , 如果采用硬编码的方式 , 则需要涉及到该对象的创建的地方
 *              都要去重新测试一遍
 *          4. 将具有类似行为的对象通过工厂来生成 可以更加 友好化 , 出自同一工厂的对象存在相同的 接口 或者 基类
 *          5. 省去了客户端一步一步的判断应该实例化什么对象 , 也就是说不必让客户端自己去一个一个的判断我需要什么对象来帮我处理事物
 *              而是 , 直接告诉工厂, 我现在有一个这样类型的事物 , 你需要给我一个对象让他来处理我的事物
 *
 *
 *
 *
 * */
abstract class Color{
    protected $name = '颜色名称';

    /**
     * @return Color
     * */
    final public static function getColor($color){
        $className = 'Color'.$color;
        return new $className;
    }


    public function show(){
        echo '当前颜色为:'.$this->name.PHP_EOL;
    }
}


class ColorRed extends Color{
    protected $name='红色';

}

class ColorYellow extends Color{
    protected $name='黄色';

}

class ColorWhite extends Color{
    protected $name='白色';

}

$color = Color::getColor('red');
$color->show();

$color = Color::getColor('white');
$color->show();